use std::net::IpAddr;

use clap::Parser;
use dirs::config_dir;
use local_ip_address::local_ip;
use serde::{Deserialize, Serialize};

use crate::data::Args;

#[derive(Clone, Debug, Serialize, Deserialize)]
struct Config {
    count: Option<u8>,
    ip: Option<IpAddr>,
    port: Option<u16>,
}

impl Default for Config {
    fn default() -> Self {
        Self {
            ip: None,
            port: Some(8080),
            count: Some(1),
        }
    }
}

pub struct Param {
    pub count: u8,
    pub filename: String,
    pub ip: IpAddr,
    pub port: u16,
    pub upload: bool,
}

pub(crate) fn get_param() -> Param {
    let config = get_config();
    let args = Args::parse();
    let filename = args.filename.unwrap_or_default();
    let count = args.count.unwrap_or(config.count.unwrap_or(1));
    let ip = local_ip().expect("获取本机ip失败");
    let ip = args.ip.unwrap_or_else(|| config.ip.unwrap_or(ip));
    let port = args.port.unwrap_or(config.port.unwrap_or(8080));
    let upload = args.upload;
    Param {
        count,
        filename,
        ip,
        port,
        upload,
    }
}

fn get_config() -> Config {
    let config_path = config_dir().map(|dir| dir.join("woof").join("config.toml"));

    match config_path {
        Some(path) => std::fs::read_to_string(path)
            .map(|str| toml::from_str::<Config>(&str).unwrap())
            .unwrap_or(Config::default()),
        _ => Config::default(),
    }
}
